package com.example.sonone.controller;

/**
 * easyExcel
 * git: https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
 * 语雀: https://www.yuque.com/easyexcel/doc/easyexcel
 */

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.example.sonone.dao.TestDao;
import com.example.sonone.pojo.CC;
import com.example.sonone.pojo.DB;
import com.example.sonone.pojo.GoodsStockLabelTree;
import com.example.sonone.pojo.Stu;
import com.example.sonone.service.TestService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("ee")
public class EasyExcelController {

    @Autowired
    private TestDao testDao;

    @PostMapping("cc")
    public CC simpleRead(@RequestBody CC cc) {

        System.out.println(cc);
        return cc;


    }


    @GetMapping("tree")
    public List<GoodsStockLabelTree> tree() {

        List<GoodsStockLabelTree> list = testDao.selectAllLabel();
        // 标签类型： 仅展示标签分类ID的状态为“启用”的 ；标签：仅展示标签状态为“启用”，且商品标签的是否展示为“展示”的商品标签名称
        List<GoodsStockLabelTree> isShowList = list.stream().filter(s -> s.getIsShow() == 1)
                .collect(Collectors.toList());
        List<GoodsStockLabelTree> goodsStockLabelTrees = buildTree(isShowList, true);

        return goodsStockLabelTrees;


    }

    private List<GoodsStockLabelTree> buildTree(List<GoodsStockLabelTree> isShowList, boolean isUseNoReasonLabel) {
        // 根据tspId 去重，防止无限递归
/*        List<GoodsStockLabelTree> isShowList = isShowListOrigin.stream()
                .collect(Collectors.
                        collectingAndThen(
                                Collectors.toCollection(() ->
                                        new TreeSet<>(Comparator.comparing(GoodsStockLabelTree::getTspId))),
                                ArrayList::new)
                );*/
        if (CollectionUtils.isNotEmpty(isShowList)) {
            // 判断是否要 无季节标签;需要，则在季节标签下新增 一个无季节
            if (isUseNoReasonLabel && true) {
                boolean hasSeasonLabel = isShowList.stream().anyMatch(s -> s.getId() == 1);
                if (hasSeasonLabel) {
                    GoodsStockLabelTree noReasonLabel = GoodsStockLabelTree.builder()
                            .id(-2)
                            .title("季节标签")
                            .type(2)
                            .pid(1)
                            .tspId("DMS_-2")
                            .tspPid("DMS_1")
                            .sourceSystem("DMS")
                            .isShow(1).build();
                    isShowList.add(noReasonLabel);
                }
            }
            Map<String, List<GoodsStockLabelTree>> treeMap =
                    isShowList.stream().collect(Collectors.groupingBy(GoodsStockLabelTree::getSourceSystem));
            List<GoodsStockLabelTree> treeList = Lists.newArrayList();
            int id = -100;
            for (Map.Entry<String, List<GoodsStockLabelTree>> entry : treeMap.entrySet()) {
                String key = entry.getKey();
                List<GoodsStockLabelTree> value = entry.getValue();
                //获取父节点
                List<GoodsStockLabelTree> collect = value.stream()
                        .filter(m -> StringUtils.isBlank(m.getTspPid()))
                        .peek(m -> m.setChildren(getChildrens(m, value)))
                        .collect(Collectors.toList());
                // 这里为了前段展示，拼上id和type
                GoodsStockLabelTree build = GoodsStockLabelTree.builder().id(id).tspId(String.valueOf(id))
                        .type(1).tspPid("").title(key)
                        .sourceSystem(key).children(collect).build();
                treeList.add(build);
                id++;
            }
            return treeList;
        }
        return Lists.newArrayList();
    }

    private List<GoodsStockLabelTree> getChildrens(GoodsStockLabelTree root, List<GoodsStockLabelTree> all) {
        List<GoodsStockLabelTree> collect = all.stream()
                .filter(m -> StringUtils.equalsIgnoreCase(m.getTspPid(), root.getTspId()))
                .peek(m -> m.setChildren(getChildrens(m, all)))
                .collect(Collectors.toList());
        return collect;
    }


    public static void main(String[] args) {
        JitOrderImportvO build1 = JitOrderImportvO.builder().subOrderId("1").build();
        JitOrderImportvO build2 = JitOrderImportvO.builder().subOrderId("2").build();
        JitOrderImportvO build3 = JitOrderImportvO.builder().subOrderId("3").build();
        JitOrderImportvO build4 = JitOrderImportvO.builder().subOrderId("1").build();
        List<JitOrderImportvO> infoList = Lists.newArrayList(build1, build2, build3, build4);
        infoList.stream().filter(s -> s.getSubOrderId().equalsIgnoreCase("1")).collect(Collectors.toList());
        Set<String> subOrderSet = infoList.stream().filter(e -> StringUtils.isNotEmpty(e.getSubOrderId()))
                .map(JitOrderImportvO::getSubOrderId)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet().stream()
                .filter(e -> e.getValue() > 1L)
                .map(e -> e.getKey()).collect(Collectors.toSet());

        System.out.println(subOrderSet);
    }


    private void getDbCenter(String sql) {
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://dbadmin-cn-new.dev.sheincorp.cn/database/executeSql";

        HttpHeaders headers = new HttpHeaders();

        headers.add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0");
        headers.add("Connection", "keep-alive");
        headers.add("cookie", "db_ticket=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkYmFk" +
                "bWluIiwianNvbiI6IjlvUjdOX200bndiMlRZZl9EQWFydlJBbWYxbVNEWVYwd1hSOTVadTNEal90eUozcjN1dVEtd1prM2t2eGdzYn" +
                "laSmE2OGhoeU9BRHNyTzlqdUhzdm1RLi4iLCJjcmVhdGUiOjE2NTUyOTgwNzEzODV9.eW3iWu59wO4v-uvmgUQ7WLQhZVFl088n5IePnVq3sr0");
        headers.add("Origin", "chrome-extension://aejoelaoggembcahagimdiliamlcdmfm");
        headers.add("Cache-Control", "no-cache");
        headers.add("Accept", "*/*");


        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("id", 31);
        map.add("sql", sql);
        map.add("dataBaseName", "dms");
        map.add("page", 1);
        map.add("limit", 100);
        map.add("sqlNoCache", false);

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);

        ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

        System.out.println(sql + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + response.getBody());
        System.out.println("====================================================================");

    }


    @PostMapping("simpleRead")
    public void simpleRead(@RequestParam("file") MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<Stu> list = Lists.newArrayList();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取 100 条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(inputStream, Stu.class, new PageReadListener<Stu>(dataList -> {
            for (Stu demoData : dataList) {
                log.info("读取到一条数据{}", JSON.toJSONString(demoData));
                list.add(demoData);
            }
        })).sheet().doRead();
        System.out.println(list);
        for (Stu db : list) {
            getDbCenter(db.getName());
        }
    }

    @PostMapping("read")
    public void read(@RequestParam("file") MultipartFile file) {
        // 写法2：
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<Stu> list = Lists.newArrayList();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(inputStream, Stu.class, new ReadListener<Stu>() {
            // 单次缓存的数据量
            public static final int BATCH_COUNT = 1;
            // 临时存储
            private List<Stu> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

            @Override
            public void invoke(Stu data, AnalysisContext context) {
                cachedDataList.add(data);
                list.add(data);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    saveData();
                    // 存储完成清理 list
                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                saveData();
            }

            // 加上存储数据库
            private void saveData() {
                log.info("{}条数据，开始存储数据库！", cachedDataList.size());
                log.info("存储数据库成功！");
                System.out.println();

            }
        }).sheet().doRead();

        System.out.println(list);
        for (Stu stu : list) {
            getDbCenter(stu.getName());
        }


    }

    @Resource
    private TestService testService;

    @PostMapping("read2")
    public void read2(@RequestParam("file") MultipartFile file) {
        // 写法2：
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<Stu> list = Lists.newArrayList();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(inputStream, Stu.class, new DemoDataListener(testService)).sheet().doRead();

        System.out.println(list);
    }

}
